<template>
  <div class="member-edit-form">
    <form-builder
      ref="form"
      :fields="fields"
      :value="value"
      :is-edit="isEdit"
      mode="member"
      @update="update"
    >
      <!-- 会员卡号 -->
      <template slot="cardNo" slot-scope="{ field }">
        <div>
          <form-item :label="field.displayName" class="member-type card-num">
            <el-input :value="value.cardNo" @input="changeCardNo" @blur="cardNoBlur" :placeholder="$t('member.components.title2')" maxlength="20"></el-input>
          </form-item>
        </div>
        <p class="card-num-desc">{{$t('member.components.title1')}}</p>
      </template>
      <!-- start 客户名称 -->
      <template slot="customer" slot-scope="{ field }">
        <form-item :label="field.displayName"  class="member-type">
          <biz-remote-select
            :value="value.customer"
            :field="field"
            :remote-method="search"
            @input="updateCustomerSelect"
            :inputDisabled="field.disabled"
            :placeholder="$t('task.tip.searchTip', {name: $t('common.base.customer')})"
            :computed-width-keys="['name']"
            cleared
          >
            <div class="customer-template-option" slot="option" slot-scope="{ option }">
              <h3>{{ option.name }}</h3>
              <p>
                <span>
                  <label>{{$t('common.base.phone')}}：</label>
                  <span>{{ option.lmPhone }}</span>
                </span>
                <span>
                  <label>{{$t('common.base.serialNumber')}}：</label>
                  <span>{{ option.serialNumber }}</span>
                </span>
                <span v-if="option && option.customerAddress">
                  <label>{{$t('common.base.address')}}：</label>
                  <span>
                    {{ option.customerAddress | fmt_address}}
                  </span>
                </span>
              </p>
            </div>
          </biz-remote-select>
        </form-item>
      </template>

      <!-- 客户编号 -->
      <template slot="customerSerialnumber" slot-scope="{ field }">
        <div>
          <form-item :label="field.displayName" class="member-type">
            <form-text :field="field" :value="value.customerSerialnumber" :placeholder="$t('member.components.title3')"></form-text>
          </form-item>
        </div>
      </template>

      <!-- 主持卡人 -->
      <template slot="mainLinkmanPhone" slot-scope="{ field }">
        <form-item :label="field.displayName" class="member-type">
          <biz-remote-select
            ref="linkman"
            :placeholder="$t('member.components.title3')"
            :value="value.linkman"
            :field="field"
            cleared
            :remote-method="searchLinkmanOuterHandler"
            @input="changeLinkman"
            :computed-width-keys="['name']"
          >
          </biz-remote-select>
        </form-item>
        <p class="card-num-desc">{{ $t('member.components.title53') }}</p>
      </template>

      <!-- 会员积分 -->
      <template slot="points" slot-scope="{ field }">
        <form-item :label="$t('member.fields.title1')" class="member-type" :validation="validateNum">
          <form-number :field="field" :value="value.points" min="0" max="1000000" @update="update" :disabled="isEdit"></form-number>
        </form-item>
      </template>

      <!-- 会员积分有效期 -->
      <template slot="pointsEffectTime" slot-scope="{ field }" v-if="value.points > 0">
        <form-item :label="$t('common.member.pointValidityPeriod')"  class="member-type card-num">
          <div>
            <TimePickRange class="time-pick-wrap" :field="field" :value="value.pointsEffectTime" :date-unit="dateUnit" :expire-date="expireDate" :rule-type="ruleType" @update="updateTime"/>
          </div>
        </form-item>
        <p class="card-num-desc">{{$t('member.components.title4')}} <span @click="jumpSetting" class="setting-color">{{ $t('member.components.title5') }}</span></p>

      </template>

      <!-- 会员余额 -->
      <template slot="balance" slot-scope="{ field }">
        <form-item :label="$t('member.fields.title3')"  class="member-type" :validation="validateBalanceNum">
          <form-number :field="field" :value="value.balance" @update="update" min="0" max="1000000" :disabled="isEdit"></form-number>
        </form-item>
      </template>


      <!-- 授权额度 -->
      <template slot="authorizationLimit" slot-scope="{ field }">
        <form-item :label="$t('member.fields.title4')"  class="member-type" :validation="validateNum">
          <form-number :field="field" :value="value.authorizationLimit" min="0" max="1000000" @update="update"></form-number>
        </form-item>
      </template>


      <!-- 会员服务费 -->
      <template slot="serviceFee" slot-scope="{ field }">
        <form-item :label="$t('member.fields.title5')"  class="member-type" :validation="validateNum">
          <form-number :field="field" :value="value.serviceFee" @update="update" min="0" max="1000000" :disabled="isEdit"></form-number>
        </form-item>
      </template>

      <!-- 服务费有效期 -->
      <template slot="serviceFeeEffectTime" slot-scope="{ field }">
        <form-item :label="$t('common.member.serviceFeeValidityPeriod')"  class="member-type card-num">
          <div>
            <TimePickRange class="time-pick-wrap" :field="field" :value="value.serviceFeeEffectTime" :date-unit="serviceDateUnit" :expire-date="serviceExpireDate" :rule-type="serviceRuleType" @update="updateServiceFeeEffectTime"/>
          </div>
        </form-item>
        <p class="card-num-desc">{{$t('member.components.title6')}} <span  @click="jumpSetting" class="setting-color">{{ $t('member.components.title5') }}</span></p>
      </template>

      <!-- 额度有效期 -->
      <template slot="limitEffectTime" slot-scope="{ field }">
        <form-item :label="$t('member.fields.title7')"  class="member-type">
          <div>
            <date-search 
              :value="value.limitEffectTime"
              :field="field"
              :need-validate="true"
              @update="update"
              :picker-options="datePickeroptions"
            />
          </div>
        </form-item>
      </template>

      <!-- 会员卡类型 -->
      <template slot="cardTypeId" slot-scope="{ field }">
        <form-item :label="field.displayName" is-not-null :validation="validateCardType" class="member-type">
          <form-select :field="field" :value="value.cardTypeId" style="display:none"></form-select>
          <el-select style="width:100%" :value="value.cardTypeId" :placeholder="$t('common.placeholder.select')" @change="updateCardType">
            <el-option v-for="item in field.setting.dataSource" :key="item.id" :label="item.membershipTypeName" :value="item.id"> </el-option>
          </el-select>
        </form-item>
      </template>

      <!-- 会员卡状态 -->
      <template slot="enabled" slot-scope="{ field }">
        <form-item :label="field.displayName"  class="member-type">
          <div>
            <el-switch
              v-model="value.enabled"
              @change="updateCardStatus"
              :active-text="value.enabled ? $t('common.base.enable') : $t('common.base.disable')"
              :active-value="1"
              :inactive-value="0"
            />
          </div>
        </form-item>
      </template>
    </form-builder>
  </div>
</template>

<script>
import MathUtil from '@src/util/math';
import { openAccurateTab } from '@src/util/platform';
import { PageRoutesTypeEnum } from 'pub-bbx-global/pageType/dist/enum/PageRoutesEnum';
import { getTaskCustomerListV2, getTaskCustomerLinkman, getCustomerByPhone } from '@src/api/TaskApi.ts';
import { customerSelectConversion } from '@src/util/conversionFunctionUtil.ts';
import TimePickRange from '@src/component/form/components/FormDate/extend/TimePickRange.vue';
import { getMemberConfig } from '@src/api/Member'
import ObjectUtil from '@src/util/lang/object.ts';
import { findComponentDownward } from '@src/util/assist'
import { customerLinkmanSelectConversion } from '@src/util/conversionFunctionUtil.ts';
import dayjs from 'dayjs';
import { safeNewDate } from '@src/util/time';
const dateUnitArr = ['year', 'month', 'day']
export default {
  components: {
    TimePickRange
  },
  props: {
    fields: {
      type: Array,
      default: () => [],
    },
    value: {
      type: Object,
      required: true,
    },
    goodsId: {
      type: String,
      default: '',
    },
    pending: {
      type: Boolean,
      default: false,
    },
    isEdit: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      loading: false,
      list: [],
      pointRule: {},
      memberServiceFeeRule: {},
      datePickeroptions: {
        disabledDate(time) {
          return time.getTime() < safeNewDate(safeNewDate().toLocaleDateString()).getTime()
        }
      }
    };
  },
  computed: {
    expireDate() {
      return this.pointRule.expireDate 
    },
    ruleType() {
      return this.pointRule.ruleType 
    },
    dateUnit() {
      let settingUnit = Number(this.pointRule.dateUnit)
      return dateUnitArr[settingUnit-1]
    },
    serviceExpireDate() {
      return this.memberServiceFeeRule.expireDate 
    },
    serviceRuleType() {
      return this.memberServiceFeeRule.ruleType 
    },
    serviceDateUnit() {
      let settingUnit = Number(this.memberServiceFeeRule.dateUnit)
      return dateUnitArr[settingUnit-1]
    },
  },
  mounted() {
    this.getMemberConfig()
  },
  methods: {
    changeCardNo(newValue) {
      let value = this.value;
      this.$set(value, 'cardNo', newValue);
      this.$emit('input', value);
    },
    cardNoBlur() {
      if(this.isEdit && !this.value.cardNo) {
        return this.$message.error(this.$t('member.components.title7'));
      }
      if (/[\u4E00-\u9FA5]/g.test(this.value.cardNo)) {
        return this.$message.error(this.$t('member.components.title8'));
      }
    },
    async getMemberConfig() {
      const { status, data, message } = await getMemberConfig();
      if (status !== 0) return this.$message.error(message);
      this.pointRule = data.memberPoints.rule
      this.memberServiceFeeRule = data.memberServiceFee.rule
      
      if(this.pointRule.ruleType == 3) {
        let startTime = dayjs().valueOf()
        let endTime = dayjs('2999-12-31 23:59:59').valueOf()
        let pointsEffectTime = [startTime,endTime]
        let value = this.value;
        this.$set(value, 'pointsEffectTime', pointsEffectTime);
        this.$emit('input', value);
      }
      if(this.memberServiceFeeRule.ruleType == 3) {
        let startTime = dayjs().valueOf()
        let endTime = dayjs('2999-12-31 23:59:59').valueOf()
        let serviceFeeEffectTime = [startTime,endTime]
        let value = this.value;
        this.$set(value, 'serviceFeeEffectTime', serviceFeeEffectTime);
        this.$emit('input', value);
      }
    },
    updateTime({newValue}) {
      if(!newValue[0] || !newValue[1] ) newValue = []
      let value = this.value;
      this.$set(value, 'pointsEffectTime', newValue);
      this.$emit('input', value);
    },
    updateServiceFeeEffectTime({newValue}) {
      if(!newValue[0] || !newValue[1] ) newValue = []
      let value = this.value;
      this.$set(value, 'serviceFeeEffectTime', newValue);
      this.$emit('input', value);
    },
    validateNum (value, field) {
      let count = MathUtil.decimalNumber(value);
      
      return new Promise((resolve, reject) => {
        if (!value) {
          return resolve(this.$t('member.components.title9', {data: field.displayName}));
        }
        if (Number(value) < 0 || Number(value) > 1000000 || count > 0) {
          return resolve(this.$t('member.components.title10'));
        }
        resolve(null);
      });
    },
    validateBalanceNum(value, field) {
      let count = MathUtil.decimalNumber(value);
      
      return new Promise((resolve, reject) => {
        if(this.isEdit) resolve(null);
        if (!value) {
          return resolve(this.$t('member.components.title65'));
        }
        if (Number(value) < 0 || Number(value) > 1000000) {
          return resolve(this.$t('member.components.title52'));
        }
        if (count > 2) {
          return resolve(this.$t('common.currency.exchangeRateLimit4'));
        }
        resolve(null);
      });
    },
    async search(params = {}) {
      try {
        const payload = {
          ...params,
          queryField: ['name', 'serialNumber', 'uuid', 'customerAddress', 'lmPhone'],
        };
        const { data } = await getTaskCustomerListV2(payload);
        if (!data || !data.list) return;
        data.list = data.list.map(customer => customerSelectConversion(customer));
        return data;
      } catch (error) {}
    },
    linkmanSelectConversion(linkman) {
      if(!linkman) return {};
      let { id, name, phone } = linkman;
      return Object.freeze({
        label: name,
        value: id,
        ...linkman
      });
    },
    updateCustomerSelect(val) {
      let value = this.value;
      this.selectedCustomer = val[0]
      this.$set(value, 'customer', val);
      let serialNumber = val?.length && val[0].serialNumber || ''
      this.$set(value, 'customerSerialnumber', serialNumber);
      this.updateLinkman()
    },
    async searchLinkmanOuterHandler(params = {}) {
      let selectCustomer = this.value?.customer && this.value?.customer[0] || {}
      let customerId = selectCustomer?.value || '';
      params.customerId = customerId
      return customerId ? this.searchLinkman(params) : this.searchCustomerByPhone(params);
    },
    async searchCustomerByPhone(params = {}) {
      let parameter = { phone: params.keyword }
      
      try {
        const result = await getCustomerByPhone(parameter);
        if (!result || !result.data) return;
        result.list = result.data.map(linkman => customerLinkmanSelectConversion(linkman))
        return result;

      } catch (error) {
        console.warn('task-edit-form: searchCustomer -> error', error);
      }
    },
    async searchLinkman(params = {}) {
      try {
        let data = await getTaskCustomerLinkman(params);
        let result = data.result;
        if (!result || !result.list) return;
        result.list = result.list.map((linkman) =>
          this.linkmanSelectConversion(linkman)
        );
        return result;
      } catch (error) {}
    },
    async updateLinkman() {
      let isHaveCustomer = this.value.customer && this.value.customer.length;
      let value = this.value;
      if(!isHaveCustomer) {
        this.$set(value, 'linkman', {});
        this.$emit('input', value);
      } else {
        let param = {
          customerId: this.selectedCustomer?.id || '',
          keyword: '',
          pageNum: 1,
          pageSize: 10,
        }
        this.searchLinkman(param).then(result => {
          let linkman = (result?.list || []).filter(item=> item?.isMain) || []
          this.$set(value, 'linkman', linkman);
        })
        this.$emit('input', value);
      }
    },
    async changeLinkman(linkman = []) {
      if (ObjectUtil.isEmpty(linkman)) {
        return console.warn('Caused: linkman is not object or is empty')
      }
      let value = this.value;
      this.$set(value, 'linkman', linkman);
      let isHaveCustomer = this.value.customer && this.value.customer.length;
      // 判断客户是否存在
      if (!isHaveCustomer) {
        // 客户不存在时则下拉框隐藏
        findComponentDownward(this.$refs.linkman, 'base-select')?.close();
      }
    },
    updateForm(val) {
      let value = this.value;
      this.$set(value, 'cardNo', val);
      this.$emit('input', value);
    },


    validate() {
      return this.$refs.form
        .validate(false)
        .then(valid => {
          return valid;
        })
        .catch(err => console.error(err));
    },
    update({ field, newValue, oldValue }) {
      let { fieldName, displayName } = field;
      if (this.$appConfig.debug) {
        console.info(
          `[FormBuilder] ${displayName}(${fieldName}) : ${JSON.stringify(
            newValue
          )}`
        );
      }
      let value = this.value;
      this.$set(value, fieldName, newValue);
      this.$emit('input', value);
    },
    updatePriceType(val) {
      let value = this.value;
      this.$set(value, 'priceType', val);
      this.$emit('input', value);
    },
    validatePrice(value, field) {
      // 小数位数
      let count = MathUtil.decimalNumber(value);

      return new Promise((resolve, reject) => {
        if (Number(value) < 0.01 || Number(value) > 99999) {
          return resolve(this.$t('goods.limit.priceRange'));
        }

        if (count > 2) {
          return resolve(this.$t('goods.limit.keepDecimal'));
        }

        resolve(null);
      });
    },
    jumpSetting() {
      openAccurateTab({
        type: PageRoutesTypeEnum.PageMemberManagement,
      });
    },
    updateCardStatus(val) {
      this.$set(this.value, 'enabled', val);
      this.$emit('input', this.value);
    },
    updateCardType(val) {
      this.$set(this.value, 'cardTypeId', val);
      this.$emit('input', this.value);
    },
    validateCardType(value, field) {
      return new Promise((resolve, reject) => {
        if (!value) {
          return resolve(this.$t('common.validate.emptyOption'));
        }
        resolve(null);
      });
    }
  },
};
</script>

<style lang="scss" scoped>
.member-edit-form {
  padding-bottom: 20px;

  ::v-deep .form-item-label {
    width: 120px;
  }

  .member-type {
    margin-bottom: 25px;
    ::v-deep .form-item-control {
      height: 33px;
      line-height: 33px;
    }
  }
  .card-num {
    margin-bottom: 25px;
    .card-num-tip {
      font-size: 12px;
      color: #8c8c8c;
    }
  }
  .card-num-desc {
      font-size: 12px;
      color: #8c8c8c;
      margin-top: -10px;
    }
  .setting-color {
    color: $color-primary-light-6;
    cursor:pointer;
  }
  ::v-deep.form-number > input {
    width: 100%!important
  }
  ::v-deep.form-number-range input {
    width: 100%!important
  }
  ::v-deep.form-number-range span {
    margin: 0
  }
}
.customer-template-option {
  * {
    margin: 0;
  }
  padding: 10px 0;
  h3 {
    font-size: 14px;
    font-weight: 500;
    line-height: 24px;
  }

  p {
    display: flex;
    justify-content: space-between;
    line-height: 24px;
    flex-wrap: wrap;
    flex-flow: column;

    & > span {
      width: 100%;
      display: flex;
      justify-content: flex-start;
      flex: 1;
      font-size: 12px;
      color: #666666;
      padding-right: 10px;

      & > label {
        padding: 0;
        min-width: 70px;
      }
    }
  }
}
</style>
